package BNS.graphs;

import java.util.Random;

/** Provides a map from integers to colours.
	In the Consensus games, there is a threat of trivialization from these strategies:
	"Everyone choose Red", 
	"Everyone choose the color we arrived at in the last game", and
	"Everyone choose the first color in the palette".
	To defeat these tactics, the ColoringPersona wants to disrupt the notion of 
	"red" being a consistent color, and the notion of "first color" being consistent
	across player interfaces. This class can be used to provide a random map
	from GUI buttons to colors. 
	*/
public class ColorMap implements java.io.Serializable {
	/**
   * 
   */
  //private static final long serialVersionUID = 1L;
  // 	TODO: Move GraphPanel.swatches into this class?
	private int[] map;
	private boolean iden;
	
	/** creates a map, to allow different players to see different button identities.
	A flag is given to indicate whether the map should be scrambled,
	or whether it should be the identity map. Games that do not need scrambling might 
	want to make the buttons all the same on every GUI, so this is an option.
	In either case, 0 always maps to 0; this is for the special (non)color White.
	@param size the number of buttons being scrambled
	@param straight a boolean indicating that the map should be identity.
	*/
	private ColorMap(boolean flag) { 
		iden= flag;
		int len= GraphPanel.swatches.length;
		if(!iden) map=new int[len];
		}
	
	/** Creates a 1:1 mapping from an integer in {1, 2,..., range} 
		to a random integer in the same set.  */
	public static ColorMap scramble(int range) {
		int size= GraphPanel.swatches.length;
		int domain= range;	// for convenience  (huh??)
		ColorMap scrmbl= new ColorMap(false);
		Random rand= new Random();
		// map is as long as swatches, but the mapping might be shorter. (hmmm)
		for (int i=0; i<size; i++) scrmbl.map[i]=i;
		for (int i=1; i<=domain; i++) {
			int r= i+rand.nextInt(range+1-i);
			int tmp= scrmbl.map[r];
			scrmbl.map[r]= scrmbl.map[i];
			scrmbl.map[i]= tmp;
			}
		return scrmbl;
		}
	
	/** Creates a simple ColorMap that implements the identity map. */
	public static ColorMap identity() { 
		return new ColorMap(true); 
		}
		
	/** This function performs the mapping for you. 
	@param i the integer to map from.
	@return what i maps to.  */
	public int map(int i) { return iden? i:map[i]; }
	
	/** Generates a few example cases to test if the class works properly. */
	public static void main(String[] args) {
		//int size= 8;
		for (int count=0; count<10; count++) {
			ColorMap cm= count==0?identity():scramble(4);
			for (int i=0; i<GraphPanel.swatches.length; i++)
				System.out.print("  "+cm.map(i));
			System.out.println();
			}
		for (int count=0; count<10; count++) {
			ColorMap cm= count==0?identity():scramble(9);
			for (int i=0; i<GraphPanel.swatches.length; i++)
				System.out.print("  "+cm.map(i));
			System.out.println();
			}
		}
	
	}
